package dev.ece.core.shader;

import java.nio.FloatBuffer;

import org.lwjgl.opengl.GL20;

import dev.ece.util.GLUtils;
import dev.ece.util.tools.BufferBuilder;

public class MatrixHandler {

	private int projectionMatrixHandler;
	
	private int modelViewMatrixHandler;
	
	private int normalMatrixHandler;
	
	private int modelViewProjectionMatrixHandler;
	
	private static FloatBuffer buffer = BufferBuilder.buildFloatBuffer(64);
	
	private static FloatBuffer normalBuffer = BufferBuilder.buildFloatBuffer(36);

	private MatrixHandler() {}
	
	public static MatrixHandler createMatrixHandler(int program) {
		MatrixHandler handler = new MatrixHandler();
		handler.projectionMatrixHandler = GL20.glGetUniformLocation(program, "ece_ProjectionMatrix");
		handler.modelViewMatrixHandler = GL20.glGetUniformLocation(program, "ece_ModelViewMatrix");
		handler.normalMatrixHandler = GL20.glGetUniformLocation(program, "ece_NormalMatrix");
		handler.modelViewProjectionMatrixHandler = GL20.glGetUniformLocation(program, "ece_ModelViewProjectionMatrix");
		return handler;
	}
	
	public void glProjectionMatrix() {
		GLUtils.getProjectionMatrix().store(buffer);
		buffer.rewind();
		GL20.glUniformMatrix4fv(projectionMatrixHandler, false, buffer);
	}
	
	public void glUniformMatrix() {
		GLUtils.computeModelViewProjectionMatrix();
		
		GLUtils.getModelViewMatrix().store(buffer);
		buffer.rewind();
		GL20.glUniformMatrix4fv(modelViewMatrixHandler, false, buffer);
		
		GLUtils.getNormalMatrix().store3f(normalBuffer);
		normalBuffer.rewind();
		GL20.glUniformMatrix3fv(normalMatrixHandler, false, normalBuffer);
		
		GLUtils.getModelViewProjectionMatrix().store(buffer);
		buffer.rewind();
		GL20.glUniformMatrix4fv(modelViewProjectionMatrixHandler, false, buffer);
	}
	
	public static String getUnimformParameterString() {
		return "uniform mat4 ece_ProjectionMatrix;\n" +
				"uniform mat4 ece_ModelViewMatrix;\n" +
				"uniform mat3 ece_NormalMatrix;\n" +
				"uniform mat4 ece_ModelViewProjectionMatrix;";
	}
	
	
	public int getProjectionMatrixHandler() {
		return projectionMatrixHandler;
	}

	public int getModelViewMatrixHandler() {
		return modelViewMatrixHandler;
	}

	public int getNormalMatrixHandler() {
		return normalMatrixHandler;
	}

	public int getModelViewProjectionMatrixHandler() {
		return modelViewProjectionMatrixHandler;
	}
	
	
}
